/**
 * Basic logic for the internal representation of a graph
 */
GraphApp.Traverse = (function () {
	var BFS, DFS, Queue, Stack;
	
	Queue = function () {
		this.memory = [];
	};
	
	Queue.prototype = {
		enqueue : function (elem) {
			this.memory.push(elem);
		},
		
		dequeue : function (elem) {
			return this.memory.shift();
		},
		
		isEmpty : function () {
			return this.memory.length === 0;
		}
	};
	
	BFS = function (graph) {
		this.graph = graph;
		this.queue = new Queue();
		this.marked = {};
		this.current = {};
		// state = 0 -> node level
		// state = 1 -> mark edges
		this.state = 0;
		this.searchValue = '';
	};
	
	BFS.prototype = {
		step : function() {
			if (this.searchValue === '' || (this.queue.isEmpty() && this.state === 0)) {
				return false;
			}
		
			if (this.state === 0) {
				this.current = this.queue.dequeue();
				if (this.current.value === this.searchValue) {
					return true;
				} else {
					this.state = 1;
					return this.current;
				}
			}
			
			if (this.state === 1) {
				var children = this.graph.neighbors(this.current.id);
				var addmarks = []
				for (var key in children) {
					var node = this.graph.nodes[children[key]];
					if (!this._isMarked(node.id)) {
						addmarks.push(node);
						this._mark(node.id);
						this.queue.enqueue(node);
					}
				}
				this.state = 0;
				return addmarks;				
			}
		},
		
		setStartingPoint : function(node) {
			this.queue.enqueue(node);
			this._mark(node.id);
		},
		
		setSearchValue : function(value) {
			this.searchValue = value;
		},
		
		_isMarked : function(id) {
			return this.marked[id];
		},
		
		_mark : function(id) {
			this.marked[id] = true;
		}
	};
	
	DFS = function (graph) {
	
	};
	
	return {
		BFS: BFS,
		DFS: DFS
	};
}());
